package nagel_schreckenberg;

import java.util.ArrayList;

import nagel_schreckenberg.Lane.Occupation;

public class State {

	private Occupation northIn;
	private Occupation eastIn;
	private Occupation southIn;
	private Occupation westIn;
	private ArrayList<Occupation> ins;
	
	public State(Occupation n, Occupation e, Occupation s, Occupation w){
		ins = new ArrayList<Occupation>();
		northIn = n;
		ins.add(northIn);
		eastIn = e;
		ins.add(eastIn);
		southIn = s;
		ins.add(southIn);
		westIn = w;
		ins.add(westIn);
	}
	
	public Occupation getNorth(){
		return northIn;
	}
	public Occupation getEast(){
		return eastIn;
	}
	public Occupation getSouth(){
		return southIn;
	}
	public Occupation getWest(){
		return westIn;
	}
	
	public boolean equals(State s){
		boolean equals = false;
		if(s.getNorth() == northIn && s.getEast() == eastIn && s.getSouth() == southIn && s.getWest() == westIn){
			equals = true;
		}
		else{
			equals = false;
		}
		return equals;
	}
	
	public PhasePolicy optimal(){
		PhasePolicy po = null;
		double full = 0;
		double regular = 0;
		double empty = 0;
		for(Occupation o : ins){
			if(o == Occupation.EMPTY){
				empty++;
			}
			else if(o == Occupation.REGULAR){
				regular++;
			}
			else{
				full++;
			}
		}
		int ct = (int)Math.round(Config.TOTALCYCLETIME / 4.0d);
		int n = ct; int e = ct; int s = ct; int w = ct;
		if(empty == 4){
			po = new PhasePolicy(ct, ct, ct, ct);
		}
		else{
			full = (1-(Config.OCCUPATION_RF-Config.OCCUPATION_ER)) / full;
			regular = (Config.OCCUPATION_RF-Config.OCCUPATION_ER) / regular;
			if(northIn == Occupation.REGULAR){
				n = (int)Math.round(Config.TOTALCYCLETIME * regular);
			}
			else if(northIn == Occupation.FULL){
				n = (int)Math.round(Config.TOTALCYCLETIME * full);
			}
			else{
				n = 0;
			}
			if(eastIn == Occupation.REGULAR){
				e = (int)Math.round(Config.TOTALCYCLETIME * regular);
			}
			else if(eastIn == Occupation.FULL){
				e = (int)Math.round(Config.TOTALCYCLETIME * full);
			}
			else{
				e = 0;
			}
			if(southIn == Occupation.REGULAR){
				s = (int)Math.round(Config.TOTALCYCLETIME * regular);
			}
			else if(southIn == Occupation.FULL){
				s = (int)Math.round(Config.TOTALCYCLETIME * full);
			}
			else{
				s = 0;
			}
			if(westIn == Occupation.REGULAR){
				w = (int)Math.round(Config.TOTALCYCLETIME * regular);
			}
			else if(westIn == Occupation.FULL){
				w = (int)Math.round(Config.TOTALCYCLETIME * full);
			}
			else{
				w = 0;
			}
			po = new PhasePolicy(n, e, s, w);
		}
		return po;
	}
}
